<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BApplication
 *
 * @author jianfeng
 */
class BlynApp extends BNode {

    const Personal_Home_Page = 'personalHome';

    //put your code here

    private $currentUser = null;
    private $db = null;
    private $appUi = null;
    private $appPool = null;
    private $activeSpace = null;
    private $activeApp = null;
    private $activeOpp = null;
    private $activeOpFlow = null;
    private $currentNode = null;
    //private $ContextApp = null;
    private $contextObj = null;
    private $count = 0;
    private $isSetDefaultTimeZone = false;
    public $basePath = null;
    protected $authPath = null;
    protected $dataPath = null;
    protected $dbPath = null;
    public $configPath = null;
    public $uiPath = null;
    public $appPath = null;
    protected $variables = array();
    public $apps = array();
    public $spaces = array();
    private $cacheManager = null;

    public function __construct() {
        //$this->initImport();
        //$config = new BApplicationConfig($this);
        //$config = $this->getConfigManager();
        //$config->init();
        parent::__construct();
        $this->setDefaultTimeZone();
    }

    public function getId($data = null) {
        //always return 1
        return 1;
    }

    /**
     *
     * @return BUser
     */
    public function getCurrentUser() {
        if ($this->currentUser == NULL) {
            $webUser = yii::app()->user;
            if ($webUser != NULL)
                $this->currentUser = new BUser($webUser->getId());
        }
        //$this->currentUser = new BUser ();
        return $this->currentUser;
    }

    public function getCurrentNode() {
        if ($this->currentNode == NULL)
            return $this;
        return $this->currentNode;
    }

    public function setCurrentNode($node = NULL) {

        if ($node == NULL) {
            $this->currentNode = $this;

            if (Blyn::app()->getActiveSpace() != NULL)
                $this->currentNode = Blyn::app()->getActiveSpace();
            if (Blyn::app()->getActiveApp() != NULL)
                $this->currentNode = Blyn::app()->getActiveApp();
            if (Blyn::app()->getActiveOperationFlow() != NULL)
                $this->currentNode = Blyn::app()->getActiveOperationFlow();
            if (Blyn::app()->getActiveOperation() != NULL)
                $this->currentNode = Blyn::app()->getActiveOperation();
        } else {
            $this->currentNode = $node;
        }

        if ($this->currentNode instanceof BSpace) {
            $this->setActiveSpace($this->currentNode);
            $app = $this->currentNode->getSpaceEngine();
            $this->setActiveApp($app);
            $this->setCurrentNode($app);
            $this->setActiveOperation(NULL);
            $this->setActiveOperationFlow(NULL);
            return;
        }
        if ($this->currentNode instanceof BApp) {
            $this->setActiveApp($this->currentNode);
            $this->setActiveOperation(NULL);
            $this->setActiveOperationFlow(NULL);
        }
        if ($this->currentNode instanceof BOperationFlow) {
            $this->setActiveOperationFlow($this->currentNode);
            $this->setActiveOperation(NULL);
        }
        if ($this->currentNode instanceof BOperation) {
            $this->setActiveOperation($this->currentNode);
        }


        //$this->currentNode->resetContextVariable(BContextObj::Scope_CurrentNode);
        /* if ($this->currentNode instanceof BSpace)
          $this->currentNode->resetContextVariable(BContextObj::Scope_Space);
          if ($this->currentNode instanceof BApp)
          $this->currentNode->resetContextVariable(BContextObj::Scope_App);
          if ($this->currentNode instanceof BOperationFlow)
          $this->currentNode->resetContextVariable(BContextObj::Scope_OperationFlow);
          if ($this->currentNode instanceof BOperation)
          $this->currentNode->resetContextVariable(BContextObj::Scope_Operation);
         * 
         */
    }

    /**
     * 
     * @param type $data
     * this function set default Space and default Space application
     * @return type
     */

    /**
     *
     * @return BAppDb
     */
    public function getAppDb() {
        if ($this->db == null)
            $this->db = new BAppDb ();

        return $this->db;
    }

    /**
     *
     * @return BUIBlyn
     */
    public function getAppUI() {
        if ($this->appUi == null) {
            $this->appUi = new BUIBlyn($this);
        }

        return $this->appUi;
    }

    public function getUIManager($style = NULL) {
        return $this->getAppUI();
    }

    public function setUIManager($appUI) {
        $this->uiManager = $appUI;
    }

    /**
     *
     * @return BAppPool 
     */
    public function getAppPool() {
        if ($this->appPool == NULL)
            $this->appPool = new BAppPool ();

        return $this->appPool;
    }

    /**
     *
     * @return BSpace
     */
    public function getActiveSpace() {
        return $this->activeSpace;
    }

    /**
     *
     * @return BApp
     */
    public function getActiveApp() {
        /* if ($this->activeApp == NULL)
          $this->activeApp = new BSpaceEngine;
         * 
         */
        if ($this->activeSpace instanceof BSpace && $this->activeApp instanceof BApp) {
            $this->activeApp->setCurrentSpace($this->activeSpace);
        }

        if ($this->activeApp instanceof BApp && get_class($this->activeApp) !== 'BApp') {
            if (!$this->activeApp->isImported)
                $this->activeApp->initImport();
        }

        return $this->activeApp;
    }

    /**
     *
     * @return BOperation
     */
    public function getActiveOperation() {
        /*
          if ($this->activeOpp == NULL && $this->getCurrentNode() instanceof BOperation)
          $this->activeOpp = $this->getCurrentNode();
         * 
         */
        if ($this->activeOpp instanceof BOperation && $this->activeApp instanceof BApp)
            $this->activeOpp->setCurrentApp($this->activeApp);

        if ($this->activeOpp instanceof BOperation && $this->activeOpFlow instanceof BOperationFlow)
            $this->activeOpp->setCurrentOperationFlow($this->activeOpFlow);
        return $this->activeOpp;
    }

    public function getActiveOperationFlow() {
        if ($this->activeOpFlow instanceof BOperationFlow && $this->activeApp instanceof BApp)
            $this->activeOpFlow->setCurrentApp($this->activeApp);
        return $this->activeOpFlow;
    }

    public function setActiveSpace($space) {
        $this->activeSpace = $space;
    }

    public function setActiveApp($app) {
        if ($app instanceof BApp) {
            if (Blyn::app()->getActiveApp() instanceof BApp) {
                if ($app->getId() != Blyn::app()->getActiveApp()->getId()) {
                    if (!$app->isImported)
                        $app->initImport();
                }
            } else {
                if (!$app->isImported)
                    $app->initImport();
            }
        }
        $this->activeApp = $app;
    }

    public function setCurrentUser($user) {
        if ($user instanceof BUser)
            $this->currentUser = $user;
    }

    public function setActiveOperation($operation) {
        if ($operation == NULL)
            $this->activeOpp = FALSE;
        else {
            $this->activeOpp = $operation;
        }
    }

    public function setActiveOperationFlow($flow) {
        $this->activeOpFlow = $flow;
    }

    public function addInstanceVariable($name, $value) {
        $this->variables[$name] = $value;
    }

    public function getInstanceVariable($name) {
        if (isset($this->variables[$name]))
            return $this->variables[$name];
    }

    public function addContextVariable($name, $value, $scope = NULL, $type = NULL) {
        //$user = $this->getCurrentUser();
        //$user->addContextVariable($name, $value);

        $tObj = $this->getContextObj();

        $tObj->addContextVariable(BContextObj::Scope_Blyn, $name, $value);
    }

    public function getContextVariable($name, $scope = NULL, $type = NULL) {
        //$user = $this->getCurrentUser();
        //return $user->getContextVariable($name);
        $tObj = $this->getContextObj();
        return $tObj->getContextVariable(BContextObj::Scope_Blyn, $name);
    }

    /**
     * 
     * @param type $data
     * @return BCacheManager
     */
    public function getCacheManager($data = NULL) {
        if ($this->cacheManager == NULL)
            $this->cacheManager = new BCacheManager ();
        return $this->cacheManager;
    }

    /**
     * 
     * @return BContextObj
     */
    public function getContextObj() {
        if ($this->contextObj == NULL)
            $this->contextObj = new BContextObj();

        return $this->contextObj;
    }

    public function setContextObj($contextObj) {
        $this->contextObj = $contextObj;
    }

    public function setDefaultTimeZone($timeZoneString = NULL) {
        $defaultTimeZone = 'Asia/Singapore';
        if ($timeZoneString != NULL)
            $defaultTimeZone = $timeZoneString;
        date_default_timezone_set($defaultTimeZone);
    }

    public function getDefaultTimeZone() {
        if (!$this->isSetDefaultTimeZone)
            $this->setDefaultTimeZone();

        return date_default_timezone_get();
    }

    public function getUnicodeId() {
        return $this->count++;
    }

    public function runApp($data = array()) {
        //set activeSpace, activeApp and activeOperation in setContext function
        //$this->setContext($data);
        //$this->setCurrentNode();

        $this->run($data);

        if ($this->getActiveSpace() != NULL)
            $this->getActiveSpace()->run($data);
        if ($this->getActiveApp() != NULL)
            $this->getActiveApp()->run($data);
        if ($this->getActiveOperationFlow() != NULL)
            $this->getActiveOperationFlow()->run($data);
        if ($this->getActiveOperation() != NULL)
            $this->getActiveOperation()->run($data);

        $this->getUIManager()->renderApp($data);
    }

    /**
     * 
     * @param type $data
     */
    public function run($data = NULL) {
        
    }

    /**
     * this function will restore active node from previous request
     */
    public function setActiveNode() {
        $lastSpaceData = Blyn::app()->getCurrentUser()->getContextVariable('b_currentSpace');
        if ($lastSpaceData != NULL) {
            $spaceId = $lastSpaceData['id'];
            if ($spaceId != NULL && $spaceId > 0)
                $space = new BSpace($spaceId);
            if ($space instanceof BSpace)
                Blyn::app()->setActiveSpace($space);
        }

        $lastAppData = Blyn::app()->getCurrentUser()->getContextVariable('b_currentApp');
        if ($lastAppData != NULL) {
            $appId = $lastAppData['id'];
            if ($appId != NULL && $appId > 0)
                $app = BApp::getAppById($appId);
            if ($app instanceof BApp)
                Blyn::app()->setActiveApp($app);
        }

        $lastOpFlowData = Blyn::app()->getCurrentUser()->getContextVariable('b_currentOperationFlow');
        if ($lastOpFlowData != NULL) {
            $opFlowId = $lastOpFlowData['id'];
            if ($opFlowId != NULL && $opFlowId > 0)
                $opFlow = new BOperationFlow($opFlowId);
            if ($opFlow instanceof BOperationFlow)
                Blyn::app()->setActiveOperationFlow($opFlow);
        }

        $lastOperationData = Blyn::app()->getCurrentUser()->getContextVariable('b_currentOperation');
        if ($lastOperationData != NULL) {
            $operationId = $lastOperationData['id'];
            if ($operationId != NULL && $operationId > 0)
                $operation = new BOperation($operationId);
            if ($operation instanceof BOperation)
                Blyn::app()->setActiveOperation($operation);
        }

        $currentNodeData = Blyn::app()->getCurrentUser()->getContextVariable('b_currentNode');

        if ($currentNodeData != NULL) {
            $class = $currentNodeData['class'];
            $id = $currentNodeData['id'];
            $currentNode = new $class($id);
            if ($currentNode instanceof BUINode) {
                Blyn::app()->setCurrentNode($currentNode);
                //Blyn::app()->getContextObj()->resetContextVariable(BContextObj::Scope_CurrentNode);
            }
        }
    }

    public function end() {
        $this->getUIManager()->postStartRender();
        Yii::app()->end();
    }

}

?>
